<template>
	<!-- 表头tips -->
	<el-table-column
		v-if="$attrs.header"
		:key="$attrs.label"
		v-bind="$attrs"
		:class-name="className"
		:min-width="minWidth"
	>
		<template slot="header" slot-scope="scope">
			<!-- tooltip提示 -->
			<template v-if="$attrs.tooltip">
				<span>{{ $attrs.label }}</span>
				<el-tooltip class="item" effect="dark">
					<i
						class="el-icon-question"
						style="position: absolute; right: -2px"
					></i>
					<div slot="content">
						<p>{{ $attrs.tipsText.split(',')[0] }}</p>
						<p>{{ $attrs.tipsText.split(',')[1] }}</p>
					</div>
				</el-tooltip>
			</template>
			<!-- popover -->
			<el-popover
				v-else-if="$attrs.popover"
				placement="top-start"
				:title="$t('common.components.tip')"
				width="280"
				trigger="hover"
			>
				<div v-if="!scope.row">
					<p>{{ $attrs.tipsText }}</p>
				</div>
				<div slot="reference" class="el-icon-question">
					<span class="other-class">{{ $attrs.label }}</span>
				</div>
			</el-popover>
			<span v-else-if="$attrs.header && $attrs.isBtn">
				<el-button
					size="mini"
					style="background:rgb(112 182 3);color:#fff;padding-right: 8px;"
					@click="handelHeader"
				>
					{{ $attrs.label }}
				</el-button>
			</span>
			<span v-else v-html="$attrs.label">
				{{ $attrs.label }}
			</span>
		</template>
		<template slot-scope="scope">
			<span v-if="scope.row" :style="filterColor($attrs, scope.row)">
				<slot v-bind="scope"></slot>
			</span>
		</template>
	</el-table-column>
	<!--判断scopedSlots.default可知道是否存在子元素-->
	<el-table-column
		v-else-if="$scopedSlots.default"
		:key="$attrs.label"
		v-bind="$attrs"
		:class-name="className"
		:min-width="minWidth"
	>
		<template slot-scope="scope">
			<span v-if="scope.row" :style="filterColor($attrs, scope.row)">
				<slot v-bind="scope"></slot>
			</span>
		</template>
	</el-table-column>
	<!--使用 slot 自定义 header-->
	<el-table-column
		v-else-if="$scopedSlots.header"
		:key="$attrs.label"
		v-bind="$attrs"
		:class-name="className"
		:min-width="minWidth"
	>
		<template slot="header" slot-scope="scope">
			<slot name="header" v-bind="scope"></slot>
		</template>
	</el-table-column>

	<!--默认情况使用原始 el-table-column-->
	<el-table-column
		v-else
		:key="$attrs.label"
		v-bind="$attrs"
		:class-name="className"
		:min-width="minWidth"
	>
		<template slot-scope="scope">
			<span v-if="scope.row" :style="filterColor($attrs, scope.row)">
				<slot v-bind="scope"></slot>
			</span>
		</template>
	</el-table-column>
</template>

<script>
import $consts from './constants'

export default {
	name: 'AfTableColumn',
	data() {
		return {
			minLength: 5, // 初始也不要写成0, 避免未及时设置宽度太丑
			getComputedWidth: 0 // 自定义列中获取元素计算的宽度
		}
	},
	computed: {
		// table数据
		values() {
			const data = this.$parent.data || []
			return data.map((item) => item[this.$attrs.prop])
		},
		// 是否自适应列宽, 默认是
		isFit() {
			return (
				(this.$parent.$attrs.autoFit === undefined &&
					this.$attrs.fit === undefined) ||
				(this.$parent.$attrs.autoFit === false &&
					this.$attrs.fit !== undefined)
			)
		},
		// 为存在scope的添加className
		className() {
			const parentClass = this.$attrs['class-name'] || ''
			const classPre =
				this.$attrs.prop ||
				`encode-${this.transChar(this.$attrs.label)}` // 有的列因为有slotScope而不给prop
			return classPre ? `${parentClass} ${classPre}-column` : ''
		},
		// 列最小宽度
		minWidth() {
			// console.log(
			// 	this.isFit,
			// 	this.$attrs.fit,
			// 	this.$attrs.label,
			// 	this.$attrs['min-width'],
			// 	'this.$attrs.label'
			// )
			if (this.$attrs.fit) return this.$attrs['min-width']
			if (!this.$attrs.label) return undefined
			if (!this.isFit) return undefined
			const isTime =
				this.$attrs.label
					.toString()
					.indexOf(this.$t('common.components.time')) !== -1
			const isret =
				(this.$attrs.label.length + 1.2) * this.fontRate.CHAR_RATE <
					this.minLength && this.$parent.data.length > 0
			const isret1 =
				!isret && !this.$attrs.sortable && this.$parent.data.length > 0
					? 12
					: 0
			const maxOne =
				Math.max(
					this.minLength,
					(this.$attrs.label.length + 1.3) * this.fontRate.CHAR_RATE
				) *
					this.fontSize +
				(this.$attrs.sortable ? 18 : 0) -
				(!isret ? 1.4 * this.fontRate.CHAR_RATE : 0) -
				isret1
			return this.$attrs.width || (isTime && this.minLength > 5)
				? maxOne - 55
				: maxOne
		},
		// 字体大小
		fontSize() {
			return (
				this.$attrs.fontSize ||
				(this.$ELEMENT || {}).fontSize ||
				$consts.fontSize
			)
		},
		// 字体比例
		fontRate() {
			return {
				...$consts.fontRate, // 默认值
				...((this.$ELEMENT || {}).fontRate || {}), // 根注册参数 (Vue.use 时的第二个参数)
				...(this.$attrs.fontRate || {}) // 父组件属性
			}
		}
	},
	watch: {
		'$parent.data': {
			immediate: true,
			deep: true,
			handler(val) {
				if (val && val.length > 0) {
					// console.log(val, val.length, 'val')
					this.isFit !== false &&
						this.$nextTick(() => {
							// 详情中的列表需要在nextTick才能生效
							if (this.$scopedSlots.default) {
								// 存在自定义节点
								setTimeout(() => {
									// 首次获取不到子节点, setTimeout才行
									// 可能存在贴边列, 需要使用包含 fixed 的类名
									const bodyWrapper = this.$attrs.fixed
										? document
												.querySelector(
													`.el-table__fixed${
														this.$attrs.fixed ===
														'right'
															? `-${
																	this.$attrs
																		.fixed
															  }`
															: ''
													}`
												)
												.querySelector(
													'.el-table__fixed-body-wrapper'
												)
										: document.querySelector(
												'.el-table__body-wrapper'
										  )
									const nodes = bodyWrapper.querySelectorAll(
										`.${this.$attrs.prop ||
											`encode-${this.transChar(
												this.$attrs.label
											)}`}-column`
									)
									if (nodes.length) {
										// 有可能会来不及获取nodes, 就切换菜单进入下一页了, 再研究吧
										const target = []
										const getComputedWidths = []
										Array.from(nodes).map((item) => {
											target.push(item.innerText)
											// 有可能存在自定义列内容超出容器, 取 scrollWidth 才行
											getComputedWidths.push(
												item.querySelector('.cell')
													.scrollWidth
											)
										})
										this.getComputedWidth = Math.min(
											...getComputedWidths
										)
										this.$set(
											this,
											'minLength',
											this.getMaxLength(target)
										)
									}
								}, 0)
							} else {
								this.$set(
									this,
									'minLength',
									this.getMaxLength(val)
								)
							}
						})
				}
			}
		}
	},
	methods: {
		handelHeader() {
			this.$parent?.$parent?.$parent?.$parent?.lockChangeHeader()
		},
		filterColor(item, val) {
			if (item.autoColor) {
				if (val[item.property] > 0) return 'color:#13ce66'
				else if (val[item.property] < 0) return 'color:red'
			}
		},
		// 获取数组中元素按字体比例最长长度
		getMaxLength(arr) {
			return arr.reduce((length, item) => {
				if (item) {
					const str = item.toString()
					const char = str.match(/[\u2E80-\u9FFF]/g)
					const charLength = char ? char.length + 0.5 : 0
					const Astr = str.match(/[a-zA-Z]/g)
					const AstrLength = Astr ? Astr.length + 1 : 0
					const num = str.match(/\d|\.|\:/g)
					const numLength = num ? num.length : 0
					// -
					const Fuguang = str.match(/-/g)
					const FuguangLength = Fuguang ? Fuguang.length : 0
					// _
					const xiahuax = str.match(/_/g)
					const xiahuaxLength = xiahuax ? xiahuax.length : 0
					//* **
					const Fuxing = str.match(/[***]/g)
					const FuxingLength = Fuxing ? Fuxing.length : 0
					// >=
					const Fuhao = str.match(/>=|<=|<|>|=|==|===/g)
					const FuhaoLength = Fuhao ? Fuhao.length : 0
					const otherLength =
						str.replace(/\s+/g, '').length -
						charLength -
						numLength -
						AstrLength -
						FuhaoLength -
						FuguangLength -
						FuxingLength -
						xiahuaxLength
					let newLength =
						charLength * 1.1 +
						AstrLength * this.fontRate.LETTER +
						FuhaoLength * 1.2 +
						FuguangLength * 1 +
						FuxingLength * 0.35 +
						xiahuaxLength * 0.12 +
						numLength * this.fontRate.NUM_RATE +
						otherLength * this.fontRate.OTHER_RATE
					if (str.includes('\n')) {
						newLength = this.getMaxLength(str.split('\n'))
					}
					if (length < newLength) {
						length = newLength
					}
				}
				return length
			}, 0)
		},
		// 转换汉字为class支持的字母
		transChar(char) {
			return encodeURIComponent(char).replace(/[^a-zA-z]/g, 'eUC')
		}
	}
}
</script>
